﻿// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)

Shader "Skybox/Cloud3d" {
Properties {
    
 
    
    [Toggle]_AA("AA",int) = 0

        _BB("BB",Range(0,1)) = 1
        _CC("CC",Range(0,1)) = 1
        _TC("_TC",Range(0,3)) = 1
 
        _Mouse ("Mouse", Vector) = (0.5, 0.5, 0.5, 0.5)
        [ToggleUI] _GammaCorrect ("Gamma Correction", Float) = 1
        _Resolution ("Resolution (Change if AA is bad)", Range(1, 1024)) = 1
        
        // 云层纹理相关
        _CloudTexture ("Cloud Texture", 2D) = "white" {}
        _CloudTextureThreshold ("Cloud Texture Threshold", Range(0, 1)) = 0.5
        _CloudTextureSpeed ("Cloud Texture Speed", Vector) = (0.1, 0.1, 0, 0)
        _CloudScale("_CloudScale", Range(0,10)) = 1
        _CloudSteps ("Cloud Steps", Range(5, 10)) = 10
        _CloudMarchDist ("Cloud March Distance", Range(0.1, 1)) = 0.35
        _CloudAmbient ("Cloud Ambient", Range(0, 10)) = 10
        _NoiseTex ("_NoiseTex", 2D) = "white" {}
        // 颜色相关属性
       _SkyColorTop ("Sky Color Top", Color) = (0.1, 0.5, 0.9, 1)
         _SkyColorBottom ("Sky Color Bottom", Color) = (0.1, 0.1, 0.9, 1)
        [HDR]_CloudColor ("Cloud Color", Color) = (1, 1, 1, 1)
 
          _SunColor ("Sun Color", Color) = (1, 1, 1, 1)
        _SunIntensity ("Sun Intensity", Range(0, 0.01)) = 0.002
        _SunPower ("Sun Power", Range(0, 5)) = 1.7

        _yScale("Scale",Range(  0.1 ,10)) = 1.6
        _yFade("_yFade",Range(0.1,1.0)) = 1.6
        _RotAlpha("_RotAlpha",Range(0,6.28)) = 0
    
}

SubShader {
    Tags { "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" }
    Cull Off ZWrite Off

    Pass {

        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #pragma target 2.0
    

        #include "UnityCG.cginc"
        float _AA;
            float _BB;
            // Built-in properties
            float4 _Mouse;
            float _GammaCorrect;
            float _Resolution;

            // 云层相关属性
            sampler2D _CloudTexture;
            float4 _CloudTexture_ST;
            sampler2D _NoiseTex;
      
            float4 _CloudTextureSpeed;
            float _CloudTextureThreshold;
            float _CloudSteps;
            float _CloudMarchDist;
            float _CloudAmbient;

            // 颜色相关属性
            float4 _SkyColorTop;
            float4 _SkyColorBottom;
            float4 _CloudColor;
     
            float4 _SunColor;
            float _SunIntensity;
            float _SunPower;
            float _TC;
        sampler2D _MainTex;
        
 

 
        inline float2 ToRadialCoords(float3 coords)
        {
            float3 normalizedCoords = normalize(coords);
            float latitude = acos(normalizedCoords.y);
            float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
            float2 sphereCoords = float2(longitude, latitude) * float2(0.5/UNITY_PI, 1.0/UNITY_PI);
            return float2(0.5,1.0) - sphereCoords;
        }
 

    

        float3 RotateAroundYInDegrees (float3 vertex, float alpha)
        {
           
            float sina, cosa;
            sincos(alpha, sina, cosa);
            float2x2 m = float2x2(cosa, -sina, sina, cosa);
            return float3(mul(m, vertex.xz), vertex.y).xzy;
        }

        struct appdata_t {
            float4 vertex : POSITION;
            UNITY_VERTEX_INPUT_INSTANCE_ID
        };

        struct v2f {
            float4 vertex : SV_POSITION;
            float3 texcoord : TEXCOORD0;
 
    
 
            UNITY_VERTEX_OUTPUT_STEREO
        };

        v2f vert (appdata_t v)
        {
            v2f o;
            UNITY_SETUP_INSTANCE_ID(v);
            UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    
            o.vertex = UnityObjectToClipPos(v.vertex);
            o.texcoord = v.vertex.xyz;
 
         
 
            return o;
        }
        inline float2 ToRadialCoordsHalf(float3 dir)
        {
            dir = normalize(dir);
    
            // Longitude: [-PI, PI] → [0, 1]
            float longitude = atan2(dir.z, dir.x);  // 水平角度
            float u = 0.5 + 0.5 * (longitude / UNITY_PI); // 映射到 [0,1]

            // Latitude from top (y = 1) to horizon (y = 0): [0, PI/2] → [0, 1]
            float latitude = acos(saturate(dir.y)); // 限制到 [0, PI/2]
            float v = latitude / (0.5 * UNITY_PI);  // PI/2 -> 1.0

            return float2(u, v);
        }
        float _RotAlpha;
        float2 DirToMatCapUV(float3 dir, float yScale)
		{

            dir = RotateAroundYInDegrees(dir,_RotAlpha);
				  // 保证输入是单位向量
			dir.y *= yScale;              // 压缩 Y 分量，增强平视区域密度

			dir = normalize(dir);   
			float2 uv = dir.xz  ;
			return uv * 0.5 + 0.5;
		}

		float3 MatCapUVToDir(float2 uv, float yScale)
		{
			float3 dir;
			dir.xz  = uv.xy * 2 - 1;
			// 计算dir.xz自身的点积
			float dotResult = dot(dir.xz, dir.xz);
			// 确保1.0 - dotResult是非负的
			dir.y = sqrt(max(0.0, 1.0 - dotResult));
			dir.y/=yScale;
		   return normalize( dir) ;
		}
        float clouds(float2 uv, float t)
        {
     
            
            float cloudValue = tex2D(_CloudTexture, uv *_CloudTexture_ST.xy+_CloudTexture_ST.zw).r;
 
            cloudValue*=_TC;
             
            return max(0, cloudValue - _CloudTextureThreshold);
        }
        float _yScale;
        float _CloudScale;
        float _yFade;
        fixed4 frag (v2f i) : SV_Target
        {
            float3 viewDir = normalize(i.texcoord);
            float4 fragColor = 0;
            float2 tc = DirToMatCapUV( viewDir,_yScale);
            float2 uv = tc; 
            float2 m = DirToMatCapUV( _WorldSpaceLightPos0.xyz,_yScale);
            float2 marchDist = _CloudMarchDist;

            float stepsInv = 1./_CloudSteps;
            float aoPower = _CloudAmbient/_CloudSteps;
            float2 sunDir = normalize(m-uv)*marchDist*stepsInv;

            float t = _Time.y;
            t = 0;

            float2 marchUv = uv;
            float cloudColor = 1.;
            float _F = smoothstep(0,_yFade,viewDir.y);
            float cloudShape = clouds(marchUv, t)*_F;


            for (float i = 0.;i<marchDist.x; i += marchDist.x*stepsInv)
            {
                marchUv += sunDir*i;
                float c = clouds(marchUv, t);
                cloudColor *= clamp(1.-c*aoPower, 0., 1.);
            } 
                 

                
                cloudColor = exp(-cloudColor)*(1.-exp(-cloudColor*2.))*2.;
                cloudColor *= cloudShape;

              
                float3 skyCol = lerp(_SkyColorBottom.rgb, _SkyColorTop.rgb, max(0,viewDir.y));
                float3 col = ((float3)0.);
                col = skyCol+cloudShape;
                
             
                float3 cloudCol = _CloudColor.rgb * cloudColor  ;
                if(_AA)
                    return cloudShape;
                col = lerp(cloudCol, col, 1.-cloudShape);

               
                float sun = _SunIntensity/pow(length(viewDir-_WorldSpaceLightPos0.xyz), _SunPower);
                col += (1.-smoothstep(0., 0.4, cloudShape))*sun*_SunColor.rgb;
                
                
                 
                fragColor = float4(sqrt(col), 1.);
                
                return fragColor;
             
      
            half4 tex = tex2D (_CloudTexture, tc);
            half3 c = tex.rgb ;
             
 
            return half4(c, 1);
        }
        ENDCG
    }
}

 
Fallback Off

}
